<?php

declare(strict_types=1);
/**
 *​
 * WxuserController.php
 * 微信用户管理API
 * User：Abell
 * Date：2020/4/18
 * Time：11:11
 */

namespace App\Controller\Abell;

use App\Constants\ErrorCode;
use App\Controller\AbstractController;
use App\Dao\WxuserDao;
use App\Service\WxuserService;
use App\Validate\WxuserValidation;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use App\Utils\ApiUtils;
use Hyperf\DbConnection\Db;
use App\Model\Wxuser as WxuserModel;
use App\Model\Wxvisit as WxvisitModel;
use App\Lib\JwtToken;
use Hyperf\Di\Annotation\Inject;
// token校验
use Hyperf\Utils\Context;
use App\Extend\Wx\Wxlogin;
use Psr\Container\ContainerInterface;
// 接口类的用户数据调用方式

/**
 * @Controller()
 */
class WxuserController extends AbstractController
{
    /**
     * @return \Psr\Http\Message\ResponseInterface
     * @Inject
     * var WxuserService
     */
    protected $service;

    /**
     * 小程序new登录注册接口 通过code获取openid 不做二次解密
     * Abell
     * 2020/4/22
     * @RequestMapping(path="/abell/wxuser/ali_login", methods="get,post")
     */
    public function aliLogin(){
        return 'helo ali login';
    }


    // 新版导出功能
    public function output(){
        $data = $this->service->output('','');
        return $this->response->download($data,'用户.csv');
    }

    /**
     * 小程序用户编辑信息查看
     * @Author abell
     * @DateTime 2020-05-26
     * @param array $request
     * @return array
     */
    public function mapInfo(){
        // 根据省来获取对应的人数
        $result = make(WxuserDao::class)->userMap();
        $provinces = make(WxuserDao::class)->mapInfo(['level_type'=>1],['province_pinyin','short_name','province']);
        $result_column = array_column($result,null,'province');
        $return_array = array(); //  { name: "南海诸岛", value: 10 },
//        $record_num = 0;  // 统计国外和未获取到用户地址信息的数据处理
        foreach ($provinces as $province_name) {
            $province_count = 0;
            // 判断省拼音是否存在记录
            if(array_key_exists($province_name['province_pinyin'],$result_column)){
                $province_count = $province_count + $result_column[$province_name['province_pinyin']]->count;
            }
            if(array_key_exists($province_name['short_name'],$result_column)){
                $province_count = $province_count + $result_column[$province_name['short_name']]->count;
            }
            array_push($return_array,['name'=>$province_name['short_name'],'value'=>$province_count]);
//            $record_num += $province_count;
        }
//        $record_all = 0;
//        foreach ($result as $res){
//            $record_all += $res->count;
//        }
//        array_push($return_array,['name'=>'国外和未知地区','value'=>($record_all - $record_num)]);
        return ['code'=>ErrorCode::SUCCESS,'msg'=>ErrorCode::getMessage(ErrorCode::SUCCESS),'data'=>$return_array];
    }

    /**
     * 小程序new登录注册接口 通过code获取openid 不做二次解密
     * Abell
     * 2020/4/22
     * @RequestMapping(path="/abell/wxuser/loginnew", methods="get,post")
     */
    public function loginnew(RequestInterface $request){
        $obj = make(Wxlogin::class);
        $data = $obj->getOpenId($request->input('code'));
        if($data){
            // 更新访问数据到统计
            $data_json = json_decode($data[2],true);
            // 成功了就是有openid  否则就含有errcode
            if(array_key_exists('errcode',$data_json)){
                // 微信返回错误
                return $this->response->json(ApiUtils::send(400,$data_json['errmsg'],$data_json,1));
            }else{
                // 微信返回正常
                $has_user = WxuserModel::where(['openid'=>$data_json['openid']])->value('id');
                if($has_user){
                    //存在的老用户登录
                    // 更新用户登录和统计数据
                    $update_user = WxuserModel::where(['openid' => $data_json['openid']])
                        ->update(['update_time' => time()]);
                    $update_visit = $this->visit($data_json['openid']);
                    $token = JwtToken::authorizations($has_user, $data_json['openid'], '2');
                    return $this->response->json(ApiUtils::send(0,'用户登录',['update_user'=>$update_user,
                        'update_visit'=>$update_visit,'token'=>$token,'openid'=>$data_json['openid']],1));
                }else{
                    // 不存在的新用户授权登录
                    // 简单写入openid和访问记录
                    $update_data = ['add_time'=>time(),'update_time'=>time(),'openid'=>$data_json['openid']];
                    if($request->has('pid')){
                        // 判断父类id是否和当前openid相同,相同就不改变父类id
                        if($request->input('pid') != $data_json['openid'])  $update_data['pid'] = $request->input('pid');
                    }
                    $new_user = WxuserModel::insertGetId($update_data);
                    $new_visit = WxvisitModel::query()->insertGetId([
                        'openid'=>$data_json['openid'],'type_explain'=>'login2reg','add_time'=>time(),'update_time'=>time()
                    ]);
                    $token = JwtToken::authorizations($new_visit, $data_json['openid'], '2');
                    return $this->response->json(ApiUtils::send(0,'用户注册',['update_user'=>$new_user,'update_visit'=>$new_visit,'token'=>$token,'openid'=>$data_json['openid']],1));
                }
            }
        }else{
            return $this->response->json(ApiUtils::send(400,'Error',$data));
        }
    }

    /**
     * 小程序二次授权接口
     * Abell
     * 2020/4/25
     * @RequestMapping(path="/abell/wxuser/logininfo", methods="get,post")
     */
    public function logininfo(RequestInterface $request){
        $obj = make(Wxlogin::class);
        $data = $obj->miniLogin($request->all());
        // 判断是否登录成功
        if($data['code']){
            // 授权失败
            return $this->response->json(ApiUtils::send(400,'Error','授权失败',1));
        }else{
            //授权成功
            //$has_user = WxuserModel::query()->where(['openid'=>$data['info']])->get();
            $userinfo = $data['info'];
            Db::table('request_log')->insertGetId([
                'visit_id' => 'ogtzs4vPpfIMWJqxjrkCmyOXSeRk',
                'path'     => '/abell/wxuser/logininfo',
                'parameter' => '获取参数用户信息='.$userinfo,
                'add_time' => time(),
                'result'   => '3微信授权成功后data='
            ]);
            // 4 处理用户信息
            $userinfo_array = json_decode($userinfo);
            Db::table('request_log')->insertGetId([
                'visit_id' => 'ogtzs4vPpfIMWJqxjrkCmyOXSeRk',
                'path'     => '/abell/wxuser/logininfo',
                'parameter' => '获取参数用户信息nickName='.$userinfo_array['nickName'],
                'add_time' => time(),
                'result'   => '4微信授权成功后data='
            ]);
            // 5 处理openid
            $data_array = json_decode($data['data'],true);
            $data_data = $data_array['data'];
            Db::table('request_log')->insertGetId([
                'visit_id' => 'ogtzs4vPpfIMWJqxjrkCmyOXSeRk',
                'path'     => '/abell/wxuser/logininfo',
                'parameter' => '获取参数用户信息nickName='.$data_array['errorCode'],
                'add_time' => time(),
                'result'   => '5微信授权成功后openid='.$data_data['openid']
            ]);
            return $this->response->json(ApiUtils::send(0,'用户登录','ok',1));
        }
    }

    /**
     * 小程序登录注册接口
     * Abell
     * 2020/4/16 15:21
     * @RequestMapping(path="/abell/wxuser/login", methods="get,post")
     */
    public function login(RequestInterface $request)
    {
        if($request->has('openid')){
            $has_user = WxuserModel::where(['openid'=>$request->input('openid')])->value('id');
            if($has_user){
                //存在的老用户登录
                $user_info = $this->checkLogin($request->all(),$has_user);
                return $this->response->json(ApiUtils::send($user_info['code'],$user_info['msg'],$user_info['token'],1));
            }else{
                // 不存在的新用户授权登录
                $user_info = $this->checkReg($request->all());
                return $this->response->json(ApiUtils::send($user_info['code'],$user_info['msg'],$user_info['token'],1));
            }
        }else{
            return $this->response->json(ApiUtils::send(500,'Error','禁止访问',1));
        }
    }

    /**
     * 小程序授权登录检查接口
     * Abell
     * 2020/4/18 15:21
     */
    public function checkLogin($request,$has_user){
        // 老用户登录,更新登录时间
        $update_user = WxuserModel::where(['id' => $has_user])
            ->update(['update_time' => time()]);
        if ($update_user) {
            // 更新登录时间成功  获取token
            $token = JwtToken::authorizations($has_user, $request['openid'], '2');
            // 统计访问
            $visit = $this->visit($has_user);
            $token['visit'] = $visit;
            $return_data = ['code'=>0,'msg'=>'登录成功','token'=>$token];
        } else {
            // 更新登录时间失败
            $return_data = ['code'=>403,'msg'=>'登录故障','token'=>''];
        }
        return $return_data;
    }

    /**
     * 小程序授权登录检查接口
     * Abell
     * 2020/4/18 15:21
     */
    public function checkReg($request){
        //新用户授权登录 post 先写入数据,后期再获取更新用户信息
        $update_data = ['add_time'=>time(),'update_time'=>time(),'openid'=>$request['openid']];
        if(array_key_exists('nickname',$request)) $update_data['nickname'] = $request['nickname'];
        if(array_key_exists('avatarurl',$request)) $update_data['avatarurl'] = $request['avatarurl'];
        if(array_key_exists('gender',$request)) $update_data['gender'] = $request['gender'];
        if(array_key_exists('country',$request)) $update_data['country'] = $request['country'];
        if(array_key_exists('province',$request)) $update_data['province'] = $request['province'];
        if(array_key_exists('city',$request)) $update_data['city'] = $request['city'];
        if(array_key_exists('language',$request)) $update_data['language'] = $request['language'];
        if(array_key_exists('mobile',$request)) $update_data['mobile'] = $request['mobile'];
        if(array_key_exists('haspay',$request)) $update_data['haspay'] = $request['haspay'];
        $new_user = WxuserModel::insertGetId($update_data);
        if($new_user){
            // 授权注册成功  获取token
            $token = JwtToken::authorizations($new_user,$request['openid'],'2');
            // 统计访问
            $visit = $this->visit($new_user);
            $token['visit'] = $visit;
            $return_data = ['code'=>0,'msg'=>'授权注册成功','token'=>$token,'visit'=>$visit];
        }else{
            // 授权注册失败
            $return_data = ['code'=>402,'msg'=>'授权注册故障','token'=>'',1];
        }
        return $return_data;
    }

    /**
     * 小程序登录注册统计接口  login2reg
     * Abell
     * 2020/4/20
     * @RequestMapping(path="/abell/wxuser/visit", methods="get,post")
     */
    public function visit($openid){
        // 查询用户当天是否已经访问过了
        $today_zero = strtotime(date('Y-m-d',time()));
        $where= ['openid'=>$openid,'type_explain'=>'login2reg'];
        $has_visit = WxvisitModel::where($where)->where('add_time', '>', $today_zero)->value('id');
        if($has_visit){
            // 存在访问数据,直接更新访问时间
            $update_data['update_time'] = time();
            $update_time = WxvisitModel::query()->where(['id'=>$has_visit])->update(['update_time'=>time()]);
            return '更新用户访问时间';
        }else{
            // 新增访问记录
            $new_visit = WxvisitModel::insertGetId([
                'openid'=>$openid,'type_explain'=>'login2reg','add_time'=>time(),'update_time'=>time()
            ]);
            return '新增用户访问记录';
        }
    }

    /**
     * 小程序签到接口
     * Abell
     * 2020/4/21
     * @RequestMapping(path="/abell/wxuser/sign", methods="get")
     */
    public function sign(RequestInterface $request)
    {
        //传入参数  openid  访问页面 从token解析获取openid
        $jwt = Context::get('jwt_token');
        // 判断用户是否存在 , 当天是否已经签到过
        $has_user = WxuserModel::query()->where(['openid' => $jwt['account']])->exists();
        if ($has_user) {
            $has_sign = Lottery::addSign($jwt['account']);
            return $this->response->json(ApiUtils::send($has_sign['code'], $has_sign['msg'], $has_sign['data'], 1));
        } else {
            return $this->response->json(ApiUtils::send(400, 'Error', '用户不存在', 1));
        }
    }

    /**
     * 小程序分享查询上级接口
     * Abell
     * 2020/4/21
     * @RequestMapping(path="/abell/wxuser/share", methods="get")
     */
    public function share(RequestInterface $request){
        $jwt = Context::get('jwt_token');
        $has_user = WxuserModel::query()->where(['openid'=>$jwt['account']])->get();
        if($has_user){
            return $this->response->json(ApiUtils::send(0,'ok',$has_user,1));
        }else{
            return $this->response->json(ApiUtils::send(400,'Error','用户不存在',1));
        }
    }

    /**
     * 小程序页面访问统计接口 PV改成UV统计 user_id改成openid
     * Abell 修改数据
     * 2020/4/22
     * @RequestMapping(path="/abell/wxuser/record", methods="get")
     */
    public function record(RequestInterface $request){
        //传入参数  openid  访问页面 从token解析获取openid
        $jwt = Context::get('jwt_token');
        if($request->has('type_explain')) {
            $today_zero = strtotime(date('Y-m-d',time()));
            // 检查当天去除同一页面重复访问
            $has_visited = WxvisitModel::query()->where(['type_explain'=>$request->input('type_explain')])
                ->where('add_time', '>', $today_zero)->value('id');
            if($has_visited){
                // 更新访问信息
                $change_visit = WxvisitModel::query()->where(['id'=>$has_visited])->update(['update_time' => time()]);
                return $this->response->json(ApiUtils::send(0,'更新访问信息',$change_visit,1));
            }else{
                // 创建访问信息
                $visit_data = [
                    'openid' => $jwt['account'],
                    'p_id'    => 1,
                    'add_time' => time(),
                    'update_time' => time(),
                    'type_explain' => $request->input('type_explain')
                ];
                $change_visit = WxvisitModel::query()->insertGetId($visit_data);
                return $this->response->json(ApiUtils::send(0,'创建访问信息',$change_visit,1));
            }
        }else{
            return $this->response->json(ApiUtils::send(400,'Error','参数不对',1));
        }

    }

}
